<script setup lang="ts">
import { onMounted, ref } from 'vue'
import {
  NButton,
  useMessage,
  useThemeVars,
  NSpin,
  NScrollbar,
  NTree,
  type TreeOption,
  type FormRules,
  type FormInst,
  NForm,
  NFormItem,
  NInput,
  NInputNumber,
  NRadioGroup,
  NRadioButton,
  type TreeSelectOption
} from 'naive-ui'
import { sendRequest } from '@/utils/api'
import type { HttpResponse } from '@/utils/http'
import type { RegionModel, RegionTreeModel } from '@/api/sysRegion'

const message = useMessage()
const primaryColor = useThemeVars().value.primaryColorHover
const regionLoading = ref(false)
const infoLoading = ref(false)
const formRef = ref<FormInst | null>(null)
const activeId = ref<number | null>(null)
const activeIdParentCode = ref<string | null>(null)
const regionOptionMap = new Map<string, TreeOption>()
const isEdit = ref(false)
const updateLoading = ref(false)
const form = ref<RegionModel | null>(null)
const nodeProps = ({ option }: { option: TreeOption }) => {
  regionOptionMap.set(option.regionCode as string, option)
  return {
    onClick() {
      activeId.value = option.id as number
      activeIdParentCode.value = option.parentRegionCode as string
      queryNodeInfo()
    }
  }
}
const formRules: FormRules = {
  shortName: {
    required: true,
    trigger: ['blur'],
    message: '简称不能为空'
  },
  fullName: {
    required: true,
    trigger: ['blur'],
    message: '全称不能为空'
  },
  orderIndex: {
    required: true,
    trigger: ['blur'],
    type: 'number',
    message: '排序码不能为空'
  }
}

// 异步加载区划
type LeafRegionModel = RegionTreeModel & {
  isLeaf: boolean
}
const viewDisabled = ref(false)
const regionOptions = ref<LeafRegionModel[]>([])

const handleAreaOptionsLoad = async (options: TreeSelectOption) => {
  regionLoading.value = true
  const [error, res] = await sendRequest<HttpResponse<RegionModel[]>>({
    module: 'sysRegion',
    api: 'list',
    uri: {
      code: options.regionCode as string
    }
  })
  regionLoading.value = false

  if (error) return message.error(error.message) && undefined
  if (res.code !== 0) return message.error(res.msg) && undefined
  if (res.data.length === 0) {
    options.isLeaf = true
    return
  }
  // @ts-ignore
  res.data.forEach((e) => (e.isLeaf = false))
  options.children = res.data as LeafRegionModel[]
}
const initAreaOptions = async () => {
  regionLoading.value = true
  const [error, res] = await sendRequest<HttpResponse<RegionModel[]>>({
    module: 'sysRegion',
    api: 'list',
    uri: {
      code: 'ROOT'
    }
  })
  regionLoading.value = false

  if (error) return message.error(error.message)
  if (res.code !== 0) return message.error(res.msg)
  // @ts-ignore
  res.data.forEach((e) => (e.isLeaf = false))
  regionOptions.value = res.data as LeafRegionModel[]
}

// 获取区划详情
const queryNodeInfo = async () => {
  isEdit.value = false
  regionLoading.value = true
  infoLoading.value = true
  const [error, res] = await sendRequest<HttpResponse<RegionModel>>({
    module: 'sysRegion',
    api: 'info',
    uri: {
      id: activeId.value as unknown as string
    }
  })
  regionLoading.value = false
  infoLoading.value = false

  if (error) return message.error(error.message)
  if (res.code !== 0) return message.error(res.msg)
  res.data.orderIndex = Number(res.data.orderIndex)
  form.value = res.data
  formRef.value?.restoreValidation()

  // if (!activeIdParentCode.value) return
  // const option = regionOptionMap.get(activeIdParentCode.value)
  // if (option) handleAreaOptionsLoad(option)
}

const submit = async () => {
  formRef.value?.validate(async (err) => {
    if (err) return

    updateLoading.value = true
    const [error, res] = await sendRequest({
      module: 'sysRegion',
      api: 'update',
      override: {
        data: form.value
      }
    })
    updateLoading.value = false

    if (error) return message.error(error.message)
    if (res.code !== 0) return message.error(res.msg)
    message.success(res.msg)
    queryNodeInfo()
  })
}

onMounted(async () => {
  initAreaOptions()
})
</script>

<template>
  <div class="region">
    <div class="card edit">
      <div class="card__title">行政区划</div>
      <NSpin
        :show="regionLoading"
        class="card__spin"
      >
        <NScrollbar>
          <NTree
            v-show="!viewDisabled"
            :node-props="nodeProps"
            :data="regionOptions"
            key-field="regionCode"
            label-field="shortName"
            block-line
            :on-load="handleAreaOptionsLoad"
          />
        </NScrollbar>
      </NSpin>
    </div>
    <div
      class="card edit"
      v-if="form"
    >
      <div class="card__title">详细信息</div>
      <NSpin
        :show="infoLoading"
        class="card__spin"
      >
        <NScrollbar style="height: calc(100% - 60px)">
          <DetailFormProvider :disabled="isEdit">
            <NForm
              :disabled="!isEdit"
              :model="form"
              :rules="formRules"
              ref="formRef"
              label-placement="left"
              label-width="130"
              size="small"
              style="padding: 15px"
            >
              <NFormItem
                label="上级行政区划代码"
                path="parentRegionCode"
              >
                <NInput
                  v-model:value="form.parentRegionCode"
                  disabled
                />
              </NFormItem>
              <NFormItem
                label="上级行政区划简称"
                path="parentShortName"
              >
                <NInput
                  v-model:value="form.parentShortName"
                  disabled
                />
              </NFormItem>
              <NFormItem
                label="行政区划代码"
                path="regionCode"
              >
                <NInput
                  v-model:value="form.regionCode"
                  disabled
                />
              </NFormItem>
              <NFormItem
                label="行政区划简称"
                path="shortName"
              >
                <NInput v-model:value="form.shortName" />
              </NFormItem>
              <NFormItem
                label="行政区划全称"
                path="fullName"
              >
                <NInput v-model:value="form.fullName" />
              </NFormItem>
              <NFormItem
                label="排序码"
                path="orderIndex"
              >
                <NInputNumber v-model:value="form.orderIndex" />
              </NFormItem>
              <NFormItem
                label="状态"
                path="regionStatus"
              >
                <NRadioGroup v-model:value="form.regionStatus">
                  <NRadioButton
                    :value="1"
                    label="正常"
                  />
                  <NRadioButton
                    :value="0"
                    label="禁用"
                  />
                </NRadioGroup>
              </NFormItem>
            </NForm>
          </DetailFormProvider>
        </NScrollbar>

        <NButton
          v-if="!isEdit"
          type="primary"
          round
          :disabled="regionLoading"
          style="margin: 13px 15px"
          @click="isEdit = true"
        >
          修改
        </NButton>
        <NButton
          v-else
          type="primary"
          round
          :loading="updateLoading"
          :disabled="updateLoading"
          style="margin: 13px 15px"
          @click="submit"
        >
          保存
        </NButton>
      </NSpin>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.region {
  display: flex;
  gap: 0 30px;
  width: 100%;
  height: 100%;

  .card {
    height: 100%;
    width: 30%;
    min-width: 400px;

    &__title {
      display: flex;
      align-items: center;
      height: 40px;
      padding: 0 1em;
      font-size: 18px;
      font-weight: 600;
      color: #fff;
      background-color: v-bind(primaryColor);
      border-radius: 3px 3px 0 0;
    }

    &__spin {
      height: calc(100% - 40px);
      border: 1px solid #d1d8e0;
      border-top: none;
      border-radius: 0 0 3px 3px;

      & :deep(.n-spin-content) {
        height: 100%;
      }
    }

    &:nth-child(2) {
      flex: 1;
    }
  }
}
</style>
